package cn.itsource.ymcc.service.impl;

import cn.itsource.ymcc.constant.KillConstants;
import cn.itsource.ymcc.constant.OrderConstants;
import cn.itsource.ymcc.constant.RConst;
import cn.itsource.ymcc.domain.CourseDoc;
import cn.itsource.ymcc.domain.CourseOrder;
import cn.itsource.ymcc.domain.CourseOrderItem;
import cn.itsource.ymcc.dto.PreOrderDto;
import cn.itsource.ymcc.exception.GlobalException;
import cn.itsource.ymcc.feign.ESCourseFeign;
import cn.itsource.ymcc.mapper.CourseOrderMapper;
import cn.itsource.ymcc.producer.IOrderProducer;
import cn.itsource.ymcc.result.JsonResult;
import cn.itsource.ymcc.service.ICourseOrderItemService;
import cn.itsource.ymcc.service.ICourseOrderService;
import cn.itsource.ymcc.utils.CodeGenerateUtils;
import cn.itsource.ymcc.vo.KillPlaceOrderVo;
import cn.itsource.ymcc.vo.PlaceOrderVo;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zongcj
 * @since 2023-09-23
 */
@Service
public class CourseOrderServiceImpl extends ServiceImpl<CourseOrderMapper, CourseOrder> implements ICourseOrderService {
    @Autowired
    private ESCourseFeign esCourseFeign;
    @Autowired
    private ICourseOrderItemService courseOrderItemService;
    @Autowired
    private IOrderProducer orderProducer;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;


    @Transactional
    @Override
    public JsonResult placeOrder(PlaceOrderVo placeOrderVo,Long userId) {
        if (checkToken(placeOrderVo.getToken())) {
            return JsonResult.error("请不要重复请求");
        }
        //生成订单编号
        String orderNo = CodeGenerateUtils.generateOrderSn(userId);


        CourseOrder order = createOrder(placeOrderVo, userId, orderNo);
        //发送一个事务消息
        rocketMQTemplate.sendMessageInTransaction(OrderConstants.MQ_COURSEORDER_PAY_GROUP_TRANSACTION,
                OrderConstants.MQ_TOPIC_ORDER_TO_PAYORDER+":"+OrderConstants.MQ_TAGS_ORDER_TO_PAYORDER,
                MessageBuilder.withPayload(JSON.toJSONString(order)).build(),
                null);


//        4. 推送下单成功站内信
        orderProducer.sendSYSTEM(order.getTitle()+"下单成功:"+ userId);

        return JsonResult.success().setData(orderNo);
    }

    private boolean checkToken(String token) {
        Boolean aBoolean = redisTemplate.hasKey(token);
        if(!aBoolean){
            return true;
        }
        redisTemplate.delete(token);
        return false;
    }

    @Override
    public JsonResult killPlaceOrder(KillPlaceOrderVo placeOrderVo, Long userId) {
        if (checkToken(placeOrderVo.getToken())) {
            return JsonResult.error("请不要重复请求");
        }
        String orderNo = placeOrderVo.getOrderNo();
//        保存订单的操作
        PreOrderDto o = (PreOrderDto)redisTemplate.opsForValue().get(KillConstants.KEY_PREFIX_PRE_ORDER + ":" + placeOrderVo.getOrderNo());
        if(o == null){
            throw new GlobalException("下单已超时！！");
        }
        CourseOrder courseOrder = new CourseOrder();
        courseOrder.setOrderNo(orderNo);
        courseOrder.setPayType(placeOrderVo.getPayType());
        courseOrder.setCreateTime(new Date());
        courseOrder.setUserId(userId);
        double v = o.getPrice().doubleValue() * o.getCount();
        BigDecimal bigDecimal = new BigDecimal(v);
        courseOrder.setTotalAmount(bigDecimal);
        courseOrder.setPayAmount(bigDecimal);
        courseOrder.setDiscountAmount(BigDecimal.ONE);
        courseOrder.setTotalCount(o.getCount().intValue());
        courseOrder.setStatusOrder(RConst.Num.INT_0);
        courseOrder.setTitle("秒杀订单");
        courseOrder.setOrderType(RConst.Num.INT_1);
//        baseMapper.insert(courseOrder);

        CourseOrderItem courseOrderItem = new CourseOrderItem();
        courseOrderItem.setAmount(bigDecimal);
        courseOrderItem.setPrice(bigDecimal);
        courseOrderItem.setCount(o.getCount().intValue());
        courseOrderItem.setCourseId(o.getKillCourseId());
        courseOrderItem.setCourseName(o.getCourseName());
        courseOrderItem.setCoursePic(o.getCoursePic());
        courseOrderItem.setOrderNo(orderNo);
        courseOrderItem.setOrderId(courseOrder.getId());
//        courseOrderItemService.save(courseOrderItem);
        ArrayList<CourseOrderItem> objects = new ArrayList<>();
        objects.add(courseOrderItem);
        courseOrder.setItemList(objects);
        //发送一个事务消息
        rocketMQTemplate.sendMessageInTransaction(OrderConstants.MQ_COURSEORDER_PAY_GROUP_TRANSACTION,
                OrderConstants.MQ_TOPIC_ORDER_TO_PAYORDER+":"+OrderConstants.MQ_TAGS_ORDER_TO_PAYORDER,
                MessageBuilder.withPayload(JSON.toJSONString(courseOrder)).build(),
                null);


//        4. 推送下单成功站内信
        orderProducer.sendSYSTEM(courseOrder.getTitle()+"下单成功:"+ userId);
        return JsonResult.success().setData(orderNo);
    }

    private CourseOrder createOrder(PlaceOrderVo placeOrderVo, Long userId, String orderNo) {
        //        2. 查询课程数据，统计课程金额
        JsonResult courseByIds = esCourseFeign.selectByCourseIds(placeOrderVo.getCourseIds());
        if(courseByIds.getSuccess()){
            CourseOrder courseOrder = new CourseOrder();
            courseOrder.setCreateTime(new Date());
            courseOrder.setOrderNo(orderNo);
            courseOrder.setPayType(placeOrderVo.getPayType());
            courseOrder.setOrderType(placeOrderVo.getType());
            courseOrder.setUserId(userId);
//            baseMapper.insert(courseOrder);

            List<CourseDoc> courses = JSON.parseArray(courseByIds.getData().toString(), CourseDoc.class);
            Double totalAmount = 0.0d;
            Double payAmount = 0.0d;
            StringBuilder title = new StringBuilder("");
            List<CourseOrderItem> items = new ArrayList<>();
            for (CourseDoc cours : courses) {
                CourseOrderItem courseOrderItem = new CourseOrderItem();
                totalAmount += cours.getPriceOld();
                payAmount += cours.getPrice();
                title.append(cours.getName());

                courseOrderItem.setAmount(new BigDecimal(cours.getPriceOld()));
                courseOrderItem.setPrice(new BigDecimal(cours.getPrice()));
                courseOrderItem.setCount(RConst.Num.INT_1);
                courseOrderItem.setCourseId(cours.getId());
                courseOrderItem.setCourseName(cours.getName());
                courseOrderItem.setCoursePic(cours.getPic());
                courseOrderItem.setOrderNo(orderNo);
//                courseOrderItem.setOrderId(courseOrder.getId());
                items.add(courseOrderItem);
            }
//        3. 保存订单以及订单明细

            courseOrder.setTotalAmount(new BigDecimal(totalAmount));
            courseOrder.setPayAmount(new BigDecimal(payAmount));
            courseOrder.setDiscountAmount(new BigDecimal(totalAmount - payAmount));
            courseOrder.setTotalCount(courses.size());
            courseOrder.setStatusOrder(RConst.Num.INT_0);
            courseOrder.setTitle(title.toString());

            courseOrder.setItemList(items);



            return courseOrder;
        }
        return null;
    }


}
